class Conteudo < ActiveRecord::Base
  belongs_to :config_conteudo
  belongs_to :conteudo_estado
  belongs_to :ca_usuario

  belongs_to :extra, :polymorphic=>true  

  has_many :categoria_conteudo, :dependent=>:destroy 
  has_many :categorias, :through => :categoria_conteudo
  has_many :ca_permissao
 
  acts_as_nested_set
  #acts_as_ferret :fields => [ :nome, :descricao, :extra ]

  has_many :tpl_escolhido

  attr_accessor :categorias_lidas
  attr_accessor :categorias_para_relacionar
  
  validates_presence_of :nome
  validates_presence_of :extra_type
  validates_presence_of :descricao,
                        :on=> :update
  validates_associated :extra,
                       :on => :update
  
  alias :original_extra :extra
  
  def extra
    if(self.extra_id)
      return original_extra 
    end
    if (@extra)
      return @extra
    else
      klass = Kernel.const_get(self.config_conteudo.classe)
      return self.extra = klass.new
    end
  end
  
  def tem_extra?
    ( ! self.extra_id.nil? ) || ( ! @extra.nil? )
  end
                
  def before_validation
  end

  def before_destroy
    self.extra.destroy
    CaPermissao.remover_todas_permissoes_conteudo(self)
  end
   
  #pega o conteudo que � inicialmente mostrado ao se acessar os conte�dos.
  #geralmente � o site, que � o topo da hierarquia.
  def self.pegar_conteudo_padrao
    Conteudo.find(:first,:conditions=>'parent_id is null')
  end
  
  ########### permissoes, etc..

  def permissao_por_grupo_e_papel(grupo_id,papel_id)
    self.ca_permissao.find(:first,:conditions=>['ca_grupo_id = ? AND ca_papel_id = ?',grupo_id,papel_id])
  end

  def pode_remover?
    self.children_count == 0
  end 

  ############# salvar e extra

  def salvar_tudo(params_conteudo,params_extra)
    self.extra.update_attributes!(params_extra)   
    self.extra_id = self.extra.id
    self.update_attributes(params_conteudo)
 end

 #cria um novo conteudo do tipo informado e o coloca como filho do atual na arvore de pastas.
 def criar(config_conteudo_id,user_id)
   conteudo = Conteudo.novo(config_conteudo_id,user_id)
   conteudo.save!
   conteudo.move_to_child_of self
   CaPermissao.cria_permissoes_novo_conteudo(conteudo)
   conteudo
  end

  def self.criar_topo_hierarquia(config_conteudo_id,user_id)
    conteudo = Conteudo.novo(config_conteudo_id)
    conteudo.save!
    conteudo
  end
  
 def self.novo(config_conteudo_id,user_id)
    config_conteudo = ConfigConteudo.find(config_conteudo_id)
    raise "Para criar um conteudo, o config conteudo deve ter ao menos a classe definida" if(config_conteudo.classe.empty?) 
    conteudo = Conteudo.new(
	   :config_conteudo_id=>config_conteudo_id,
	   :nome=>"Novo(a) "+config_conteudo.nome,
     :extra_type=>config_conteudo.classe,
	   :conteudo_estado_id=>1,
     :data_inicial=>Time.now,
	   :ca_usuario_id=>user_id
    )
    conteudo
  end

  
  def before_update
   #para cada categorizacao que este tipo de conteudo deve ter.
   config_conteudo.config_conteudo_categorizacao.each do |categorizacao|
     id_categorizacao = categorizacao.categoria_id
     # vê se está definida em categorias_para_relacionar (parâmetro recebido !?)
     if(!categorias_para_relacionar.nil?)
       if(categorias_para_relacionar.key?(id_categorizacao) && (categorias_para_relacionar[id_categorizacao] > 0) )
         # verifica se j� existe relacionamento para esta categorizacao
         existe = false
         categoria_conteudo.each do |c|
           #entrando neste if, � pq existe
           if (c.categoria.categorizacao_id == id_categorizacao)
             existe = true
             # se o que existe para a categorizacao for diferente do recebido em categorias_para_relacionar, atualiza
             if (categorias_para_relacionar[id_categorizacao] != c.categoria_id) 
               pp('>>>>>>>>>>>>>>>>>>EXISTE - ALTERANDO')
               c.categoria_id = categorias_para_relacionar[id_categorizacao]
               c.save!
             end #if 
           end
         end #do
       end # if
       # se ainda n�o existe, cria
       if(!existe) 
         categoria_conteudo.create({"categoria_id"=>categorias_para_relacionar[id_categorizacao]})
       end # if
     # se n�o est� definida
     else
       categoria_conteudo.create({"categoria_id"=>id_categorizacao})
     end # else
   end #do
  end
  
  ############### templates

  def id_tpl_escolhido_por_config(config_conteudo_id)
    tpl_escolhido = self.tpl_escolhido.find(:first,:conditions=>'config_conteudo_id = '<<config_conteudo_id.to_s)
    tpl_escolhido ? tpl_escolhido.tpl_id : false
  end

  def tpl_escolhido_por_config(config_conteudo_id)
    tpl_escolhido = self.tpl_escolhido.find(:first,:conditions=>'config_conteudo_id = '<<config_conteudo_id.to_s)
    tpl_escolhido ? tpl_escolhido.tpl : false
  end

  def id_tpl_escolhido()
    tpl_escolhido = self.tpl_escolhido.find(:first,:conditions=>'config_conteudo_id = '<<self.config_conteudo_id.to_s)
    tpl_escolhido ? tpl_escolhido.tpl_id : false
  end

  def tpl()
    tpl_escolhido = self.tpl_escolhido.find(:first,:conditions=>'config_conteudo_id = '<<self.config_conteudo_id.to_s)
    tpl_escolhido ? tpl_escolhido.tpl : false
  end
  
  #pega o template escolhido, ou o do pai que tiver escolhido. 
  def decidir_tpl
    tpl = self.tpl
    if (tpl == false)
      pegar_tpl_dos_pais
    else
      tpl
    end
  end

  def pegar_tpl_dos_pais
    pai = self.parent
    while(pai)
      tpl = pai.tpl_escolhido_por_config(self.config_conteudo_id)
      return tpl if(tpl)
      pai = pai.parent
    end
    #false
    throw "Não há template definido na hierarquia para este tipo de conteúdo ("<<self.config_conteudo.nome<<"). Defina um tipo no topo da hierarquia por garantia."
  end
  
  def texto_tpl
    self.decidir_tpl.texto
  end
  
  ############## anexos

  #retorna os filhos desse conteudo que s�o anexos (config_conteudo tem par�metro anexo true).
  def arquivos
    pp(self.children)
    self.children
  end

  ############### categorias

  #l� as categorias que s�o relacionadas a cada categoriza��o que esse tipo de conteudo permite.
  def carregar_categorias
    @categorias_lidas = Hash.new
    config_conteudo.config_conteudo_categorizacao.each do |categorizacao|
      tem = false
      categoria_conteudo.each do |categoria_conteudo|
	      if(categoria_conteudo.categoria.categorizacao_id == categorizacao.categoria_id)
	        @categorias_lidas[categorizacao] = categoria_conteudo.categoria
	        tem = true
	      end
      end
      @categorias_lidas[categorizacao] = nil if !tem
    end
  end

  def idsCategorizacoes
    if @categorias_lidas.nil? 
      carregar_categorias
    end
    ids = []
    @categorias_lidas.each_key do |cat|
      ids << cat.categoria_id
    end
    ids
 end

 ################ gerencia da cole�ao de filhos

  def avanca?
    sql = self.parent_id ? "lft > ? AND parent_id = ?" : "lft > ? AND parent_id IS ?"
    Conteudo.count(:all, :conditions=>[sql,self.lft,self.parent_id]) > 0
  end

  def avancar
    #acha o pr�ximo
    sql = self.parent_id ? "lft > ? AND parent_id = ?" : "lft > ? AND parent_id IS ?"
    proximo = Conteudo.find(:first, :conditions=>[sql,self.lft,self.parent_id], :order=>'lft')
    #move
    self.move_to_right_of proximo
  end
  
  def volta?
    sql = self.parent_id ? "lft < ? AND parent_id = ?" : "lft < ? AND parent_id IS ?"
    Conteudo.count(:all, :conditions=>[sql,self.lft,self.parent_id])> 0
  end

  def voltar
    #acha o anterior
    sql = self.parent_id ? "lft < ? AND parent_id = ?" : "lft < ? AND parent_id IS ?"
    anterior = Conteudo.find(:first, :conditions=>[sql,self.lft,self.parent_id], :order=>'lft desc')
    #move
    self.move_to_left_of anterior
  end
end